package com.wink.admin.config;


import com.wink.admin.common.exception.CustomException;
import com.wink.admin.common.response.ApiResponse;
import com.wink.admin.common.response.ResultCode;
import com.wink.admin.utils.ResponseUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ValidationException;
import java.util.stream.Collectors;

/**
 * @author donaldhan
 */
@ControllerAdvice
public class GlobalExceptionHandler {
    private Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 运行异常处理
     */
    @ExceptionHandler(value = RuntimeException.class)
    @ResponseBody
    public ApiResponse runtimeExceptionErrorHandle(RuntimeException e) {
        logger.error(e.getMessage(), e);
        return ResponseUtils.setResult(ResultCode.FAIL, e.getMessage());
    }

    /**
     * 全局异常处理
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ApiResponse defaultErrorHandler(Exception e) {
        logger.error(e.getMessage(), e);
        return ResponseUtils.setResult(ResultCode.FAIL, e.getMessage());
    }

    /**
     * 空指针异常处理
     */
    @ExceptionHandler(value = NullPointerException.class)
    @ResponseBody
    public ApiResponse nullPointerExceptionErrorHandle(NullPointerException e) {
        logger.error(e.getMessage(), e);
        return ResponseUtils.setResult(ResultCode.NULL_FAIL, e.getMessage());
    }

    /**
     * 验证异常处理
     */
    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    @ResponseBody
    public ApiResponse bindExceptionErrorHandle(BindException e) {
        logger.error("参数验证异常,BindException:", e);

        //  TODO: 2020/11/9 WINK 这里可以补充其他参数校验异常的msg
        return ResponseUtils.setResult(ResultCode.PARAM_VALID_ERROR, e
                .getBindingResult()
                .getAllErrors()
                .stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.joining(",")));
    }

    /**
     * 业务异常处理
     */
    @ExceptionHandler(value = CustomException.class)
    @ResponseBody
    public ApiResponse customExceptionErrorHandle(CustomException e) {
        logger.error(e.getMessage(), e);
        if (e.getCode() == null) {
            return ResponseUtils.setResult(ResultCode.REPEAT_SUBMIT_FAIL.getCode(), e.getMessage());
        }
        return ResponseUtils.setResult(e.getCode(), e.getMessage());
    }


    // @ExceptionHandler(value = ConstraintViolationException.class)
    // @ResponseBody
    // public ApiResponse constraintViolationExceptionHandle(ConstraintViolationException e) {
    //     logger.error("ConstraintViolationException,{}", e);
    //     Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
    //     StringBuffer errMessage = new StringBuffer();
    //     for (ConstraintViolation<?> result : constraintViolations) {
    //         errMessage.append(result.getMessage()).append(";");
    //     }
    //     return ResponseUtils.setResult(-1, errMessage.toString());
    // }
}